package com.itheima.utils;


import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

/*用于记录日志的工具类,它里面提供了公共的代码
* */


//spring基于注解的aop通知     最终通知执行在异常通知之前
//而利用环绕通知   异常通知  在 最终通知之前

@Component("logger")
@Aspect//表示当前是一个切面类
public class Logger {

    @Pointcut("execution(* com.itheima.service.impl.*.*(..))")   //切入点表达式
    public void pt1(){

    }


    //前置通知
    /*用于打印日志 ,计划让其在切入点方法执行之前执行(切入点方法就是业务层方法)*/
 //   @Before("pt1()")
    public void printLog(){
        System.out.println("前置通知执行即:logger开始执行日志");
    }


    //后置通知
 //   @AfterReturning("pt1()")
    public void afterLog(){
        System.out.println("后置通知执行即:logger开始执行日志");
    }


    //异常通知
 //   @AfterThrowing("pt1()")
    public void exceptionLog(){
        System.out.println("异常通知执行即:logger开始执行日志");
    }

    //最终通知
 //   @After("pt1()")
    public void finalLog(){
        System.out.println("最终通知执行即:logger开始执行日志");
    }


    /*有了环绕通知不需要在配置文件中单独写前置通知  后置通知 异常通知 最终通知 更加省懒*/


    //环绕通知    一个方法配置四个通知
    @Around("pt1()")
    public Object arroundLog(ProceedingJoinPoint pjp)  {
        Object rtvalue=null;

        try{
            Object[] args = pjp.getArgs();  //得到方法执行所需的参数
            System.out.println("前置通知");
            rtvalue=pjp.proceed(args);      //明确切入点方法
            System.out.println("后置通知");
            return rtvalue;

        }catch(Throwable t){
            System.out.println("异常通知");
            throw new RuntimeException(t);
        }finally {
            System.out.println("最终通知");
        }

    }

}
